package main

import (
	"encoding/json"
	"github.com/go-redis/redis"
	"github.com/jasonlvhit/gocron"
	"github.com/jmoiron/sqlx"
	"log"
	"znzc_monitor/alive"
	"znzc_monitor/configs"
	"znzc_monitor/dao"
	"znzc_monitor/domain"
)

//https://www.cnblogs.com/zhzhlong/p/12511650.html

/**

1.统计各个监控维度信息
2.定义各个维度聚合对象
3.把数据推到redis中,key定义为ip
4.新建websocket工程项目,订阅redis监控信息
5.前后端对接websocket信息

//定义探针,探测各个主机的存活情况,探针定义在收集器中,因为收集器是部署在各个监控主机中，和要监控的主机进行一一绑定的
//主机ip信息从数据库中读取
//websocket工程主要是用来进行数据拉取，根据前端界面的需要定义不同的端点,主要是因为前端图表数据展示实时性的缘故

//端点信息配置  redis信息配置  监控主机ip配置   磁盘监控路径配置   cpu监控配置 gpu监控配置
//收集器启动检查：端点测试（curl） 监控主机ip检查

*/

//获取磁盘信息  --占比(%)
//获取内存信息  --占比(%)
//获取CPU信息  --占比(%)
//获取网卡流量信息  --网卡名称  接收 发送 速度
//获取GPU信息  --温度(c)  使用占比(%)  使用情况(MiB)
func main() {

	viper()

	var exist = false
	collectorIp := configs.GetCollectorIp()

	client := dao.OpenRedis()

	Db, err := dao.OpenDataBases()
	if err != nil {
		panic(err.Error())
	}

	//系统监控信息收集频率
	collectionRate := configs.GetCollectionRate()

	//协程执行配置信息检查,实现手动退出监控程序
	go func(*redis.Client, *sqlx.DB) {

		s := gocron.NewScheduler()

		//每半小时检查一次
		_ = s.Every(30).Minute().Do(func() {

			servers := dao.SelectInfo(Db)

			if servers != nil {
				for _, server := range servers {
					if server.Ip == collectorIp {
						exist = true
					}
				}
			}

			if !exist {
				panic("数据库没有配置该收集器ip信息")
			}

		}, collectorIp, client)

	}(client, Db)

	server := dao.SelectOneByIp(Db, collectorIp)

	s := gocron.NewScheduler()

	_ = s.Every(collectionRate).Seconds().Do(collectSystemInfo, collectorIp, client, server, collectionRate)

	// keep the channel
	sc := s.Start()

	defer client.Close()

	checkAlive := configs.GetCheckAlive()

	//监测服务器是否存活
	alive.CheckAlive(checkAlive)

	// it will happens if the channel is closed
	<-sc

}

func viper() {

	//vipConfig是配置
	vipConfig, err := configs.Init()

	log.Println("config.init error是:", err)

	log.Println("config.init vipConfig是:", vipConfig)

}

/**
  每隔10秒收集以及系统信息
*/
func collectSystemInfo(collectorIp string, client *redis.Client, server *domain.Server, collectionRate uint64) {

	log.Println("监控信息收集频率为：", collectionRate, "秒收集一次")
	//组装监控信息结果
	monitor := new(domain.Monitor)
	network := domain.Network{}
	_ = network.NetWorkInfo()
	cpu := domain.Cpu{}
	_ = cpu.CpuInfo()
	gpu := domain.Gpu{}
	gpu.GpuInfo()
	disk := domain.Disk{}
	_ = disk.DiskInfo(configs.GetDiskInfo())
	memory := domain.Memory{}
	_ = memory.MemoryInfo()
	monitor.Network = network
	monitor.Cpu = cpu
	monitor.Gpu = gpu
	monitor.Disk = disk
	monitor.Memory = memory
	monitor.CollectorIp = collectorIp

	monitor.Id = server.Id
	monitor.Ip = server.Ip
	monitor.Name = server.Name
	monitor.MaxTaskNum = server.MaxTaskNum

	b, _ := json.Marshal(monitor)
	log.Println("监控信息为：", string(b))
	_ = dao.Publish(client, string(b))

}
